import * as Koa from 'koa';
import { Transaction } from 'tiny-entity2';
import { Guid, route, RouteOptionsVerify, ServiceManager, UsingLock } from "../../common";
import { ServiceException } from '../../common/excpetion';
import { ApiDataContext } from '../../domain/apiDataContext';
import { Organization } from '../../domain/models/organization';
import { OrganizationTree } from '../../domain/models/organizationTree';
import { DepartmentService } from '../../service/DepartmentService';
import { OrganizationService } from '../../service/organizationService';
import { OrganizationTreeService } from '../../service/organizationTreeService';
const orgSvr = ServiceManager.Current.GetService<OrganizationService>('OrganizationService');
const orgTreeSvr = ServiceManager.Current.GetService<OrganizationTreeService>('OrganizationTreeService');

class OrganizationController {
    @route(new RouteOptionsVerify('GET', '/api/organization'))
    async queryOrganizations(ctx: Koa.Context, next) {
        let params = ctx.query;
        let organization = await orgSvr.QueryOrganization(params);
        ctx.response.body = organization;
        await next();
    }

    @route(new RouteOptionsVerify('GET', '/api/organization/:id'))
    async getOrganizationInfoById(ctx: Koa.Context, next) {
        let id = ctx.params.id;
        let data = await orgSvr.GetOrganizationById(id);
        let orgtrees: OrganizationTree[] = await orgTreeSvr.QueryOrganizationTree({ objectName: "organization", objectId: id });
        data.orgTree = <OrganizationTree>{};
        if (orgtrees && orgtrees.length > 0) {
            data.orgTree = orgtrees[0];
        }

        ctx.response.body = data;
        await next();
    }
    @route(new RouteOptionsVerify('POST', '/api/organization'))
    async createOrganization(ctx: Koa.Context, next) {
        let rootOrgId = ctx.headers['orgid'];
        let org: Organization = ctx.request.body;

        checkOrgData(org);
        var today = Date.now();
        org.modifyTime=today;
        org.isDelete=false;
        org.id=Guid.GetGuid();
        ctx.response.body = await UsingLock(org.name, async () => {
            return await Transaction(new ApiDataContext(), async datactx => {
                let result = await orgSvr.CreateOrganization(org, datactx);
                let orgTree = new OrganizationTree();
                orgTree.id = Guid.GetGuid();
                orgTree.isDelete = false;
                if(rootOrgId && rootOrgId!="")
                {
                    orgTree.organizationId =rootOrgId;
                    orgTree.isRoot = false;
                }
                else
                {
                    orgTree.organizationId =result.id;
                    orgTree.isRoot = true;
                }
                
                orgTree.objectId = result.id;
                orgTree.objectName = result.ClassName();
              
                orgTree.nodeName = result.name;
                orgTree.parentId= org.orgTree.parentId;

                result.orgTree = await orgTreeSvr.CreateorganizationTree(orgTree, datactx);
                return result;
            });
        })

        await next();
    }
    @route(new RouteOptionsVerify('PUT', '/api/organization'))
    async updateOrganization(ctx: Koa.Context, next) {
        let org: Organization = ctx.request.body;
        if (!org.id) {
            throw new ServiceException('id 不能为空！', 'not_be_null');
        }
        checkOrgData(org);
        var today = Date.now();
        org.modifyTime=today;
        ctx.response.body = await UsingLock(org.id, async () => {
            return await Transaction(new ApiDataContext(), async datactx => {
                let orgData = await orgSvr.GetOrganizationById(org.id);
                orgData.name=org.name?org.name:orgData.name;
                orgData.phone=org.phone?org.phone:orgData.phone;
                orgData.createTime=org.createTime?org.createTime:orgData.createTime;
                orgData.legalName=org.legalName?org.legalName:orgData.legalName;
                orgData.province=org.province?org.province:orgData.province;
                orgData.city=org.city?org.city:orgData.city;
                orgData.area=org.area?org.area:orgData.area;
                orgData.address=org.address?org.address:orgData.address;
                orgData.businessLicenseUrl=org.businessLicenseUrl?org.businessLicenseUrl:orgData.businessLicenseUrl;
                orgData.code=org.code?org.code:orgData.code;
                orgData.orgCodeUrl=org.orgCodeUrl?org.orgCodeUrl:orgData.orgCodeUrl;
                orgData.logo=org.logo?org.logo:orgData.logo;
                orgData.status=org.status?org.status:orgData.status;
                orgData.isDelete=org.isDelete?org.isDelete:orgData.isDelete;
                orgData.modifyTime=org.modifyTime?org.modifyTime:orgData.modifyTime;
                orgData.creditCode=org.creditCode?org.creditCode:orgData.creditCode;
               // orgData.ConverToEntity(org);

                let result = await orgSvr.UpdateOrganization(orgData, datactx);
                orgData.orgTree.nodeName = org.name;
                result.orgTree = await orgTreeSvr.UpdateorganizationTree(orgData.orgTree, datactx);
                return result;
            });
        })

        await next();
    }
    @route(new RouteOptionsVerify('DELETE', '/api/organization/:id'))
    async deleteOrganization(ctx: Koa.Context, next) {
        let id = ctx.params.id;

        if (!id) {
            throw new ServiceException('id 不能为空！', 'not_be_null');
        }
        let organization = await orgSvr.GetOrganizationById(id);
        organization.isDelete = true;

        ctx.response.body =await UsingLock(organization.id, async () => {
            return await Transaction(new ApiDataContext(), async datactx => {
                let result =await orgSvr.UpdateOrganization(organization,datactx);
                organization.orgTree.isDelete=true;
                await orgTreeSvr.UpdateorganizationTree(organization.orgTree, datactx);
                return result;
            })
        })

        await next();
    }
}



const checkOrgData = (org: Organization) => {

    if (!org.name) {
        throw new ServiceException('未填写组织名称！');
    }
    if (!org.code) {
        throw new ServiceException('未填写组织代码！');
    }
   
}